package com.gitee.jmash.rbac.client.token;

import com.gitee.jmash.common.cache.SerialCache;
import com.gitee.jmash.common.config.AppProps;
import com.gitee.jmash.common.grpc.auth.OAuth2Credentials;
import com.gitee.jmash.common.utils.ConfigSecretUtil;
import com.gitee.jmash.core.utils.NetSecretUtil;
import com.gitee.jmash.rbac.client.RbacClientConfig;
import com.google.protobuf.BoolValue;
import jakarta.enterprise.inject.spi.CDI;
import jmash.rbac.RbacGrpc;
import jmash.rbac.protobuf.LoginReq;
import jmash.rbac.protobuf.LogoutReq;
import jmash.rbac.protobuf.TokenResp;
import org.eclipse.microprofile.config.inject.ConfigProperties;

public class SystemAccessToken {

  /** 缓存. */
  public static SerialCache getCache() {
    return CDI.current().select(SerialCache.class).get();
  }

  /** 应用配置. */
  public static AppProps getAppProps() {
    return CDI.current().select(AppProps.class, ConfigProperties.Literal.NO_PREFIX).get();
  }

  /** 客户端认证配置. */
  public static ClientAuthProps getClientAuthProps() {
    return CDI.current().select(ClientAuthProps.class, ConfigProperties.Literal.NO_PREFIX).get();
  }

  /** 创建系统访问Token. */
  public static String getAccessToken(String tenant) {
    AppProps appProps = getAppProps();
    String key = "systoken:" + tenant + ":" + appProps.getName();
    if (getCache().containsKey(key)) {
      return (String) getCache().get(key);
    }
    TokenResp token = login(tenant, appProps.getName());
    String accessToken = token.getAccessToken();
    getCache().put(key, accessToken, token.getExpiresIn() - 300);
    return accessToken;
  }

  /** 清理系统访问Token. */
  public static void clearAccessToken(String tenant) {
    AppProps appProps = getAppProps();
    String key = "systoken:" + tenant + ":" + appProps.getName();
    if (getCache().containsKey(key)) {
      String accessToken = (String) getCache().get(key);
      getCache().remove(key);
      logout(tenant, appProps.getName(), accessToken);
    }
  }

  /** 登录系统. */
  public static TokenResp login(String tenant, String clientId) {
    ClientAuthProps props = getClientAuthProps();
    String pwd = ConfigSecretUtil.decrypt(props.getPassword());
    String encodePwd = NetSecretUtil.encrypt(pwd);
    RbacGrpc.RbacBlockingStub rbacStub =
        RbacGrpc.newBlockingStub(RbacClientConfig.getManagedChannel());
    LoginReq request = LoginReq.newBuilder().setTenant(tenant).setDirectoryId("jmash")
        .setUserName(props.getUsername()).setEncodePwd(encodePwd).setClientId(clientId).build();
    return rbacStub.login(request);
  }

  /** 退出登录系统. */
  public static BoolValue logout(String tenant, String clientId, String accessToken) {
    RbacGrpc.RbacBlockingStub rbacStub =
        RbacGrpc.newBlockingStub(RbacClientConfig.getManagedChannel())
            .withCallCredentials(new OAuth2Credentials(accessToken));
    LogoutReq request = LogoutReq.newBuilder().setTenant(tenant).setAccessToken(accessToken)
        .setClientId(clientId).build();
    return rbacStub.logout(request);
  }

}
